using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using JGSY.CMS.LowCode.Platform.Infrastructure.Configuration.Models;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Configuration
{
    /// <summary>
    /// 集中化存储配置管理器
    /// 统一管理所有存储相关配置，避免重复和不一致
    /// </summary>
    public class CentralizedStorageConfigurationManager
    {
        private readonly IConfiguration _configuration;
        private readonly ILogger<CentralizedStorageConfigurationManager> _logger;
        private CentralizedStorageConfiguration? _cachedConfig;

        public CentralizedStorageConfigurationManager(
            IConfiguration configuration,
            ILogger<CentralizedStorageConfigurationManager> logger)
        {
            _configuration = configuration;
            _logger = logger;
        }

        /// <summary>
        /// 获取集中化存储配置
        /// </summary>
        public CentralizedStorageConfiguration GetStorageConfiguration()
        {
            if (_cachedConfig != null)
            {
                return _cachedConfig;
            }

            var config = new CentralizedStorageConfiguration();
            
            // 1. 检查是否已经使用集中化配置
            var centralizedSection = _configuration.GetSection("Storage");
            if (centralizedSection.Exists() && centralizedSection.GetChildren().Any())
            {
                _logger.LogInformation("使用集中化存储配置");
                config = centralizedSection.Get<CentralizedStorageConfiguration>() ?? config;
            }
            else
            {
                _logger.LogInformation("从传统配置迁移到集中化存储配置");
                config = MigrateFromLegacyConfiguration();
            }

            _cachedConfig = config;
            return config;
        }

        /// <summary>
        /// 重新加载配置（清除缓存）
        /// </summary>
        public void RefreshConfiguration()
        {
            _cachedConfig = null;
            _logger.LogInformation("存储配置缓存已清除，下次访问将重新加载");
        }

        /// <summary>
        /// 验证配置有效性
        /// </summary>
        public CentralizedConfigurationValidationResult ValidateConfiguration()
        {
            var result = new CentralizedConfigurationValidationResult();
            var config = GetStorageConfiguration();

            // 验证本地存储配置
            ValidateLocalStorageConfiguration(config.Local, result);

            // 验证云存储配置
            ValidateCloudStorageConfiguration(config, result);

            return result;
        }

        /// <summary>
        /// 从传统配置迁移
        /// </summary>
        private CentralizedStorageConfiguration MigrateFromLegacyConfiguration()
        {
            var config = new CentralizedStorageConfiguration();

            // 迁移上传配置 -> 本地存储配置
            var uploadSection = _configuration.GetSection("Upload");
            if (uploadSection.Exists())
            {
                config.Local = new UploadConfiguration
                {
                    MaxFileSize = uploadSection.GetValue<long>("MaxFileSize", 10485760),
                    AllowedExtensions = uploadSection.GetSection("AllowedExtensions")
                        .Get<List<string>>() ?? new List<string> { ".jpg", ".jpeg", ".png", ".gif", ".pdf" },
                    UploadPath = uploadSection.GetValue<string>("UploadPath") ?? "wwwroot/uploads",
                    BaseUrl = uploadSection.GetValue<string>("BaseUrl") ?? "/uploads"
                };

                _logger.LogInformation("已迁移Upload配置到Local存储配置");
            }

            // 迁移云存储配置
            var cloudSection = _configuration.GetSection("CloudStorage");
            if (cloudSection.Exists())
            {
                config.CloudProvider = cloudSection.GetValue<string>("DefaultProvider") ?? "Local";

                // 迁移阿里云OSS配置
                var aliyunSection = cloudSection.GetSection("AliyunOss");
                if (aliyunSection.Exists())
                {
                    config.AliyunOSS = aliyunSection.Get<AliyunOssConfiguration>();
                    _logger.LogInformation("已迁移AliyunOss配置");
                }

                // 迁移腾讯云COS配置
                var tencentSection = cloudSection.GetSection("TencentCos");
                if (tencentSection.Exists())
                {
                    config.TencentCOS = tencentSection.Get<TencentCosConfiguration>();
                    _logger.LogInformation("已迁移TencentCos配置");
                }

                // 迁移华为云OBS配置
                var huaweiSection = cloudSection.GetSection("HuaweiObs");
                if (huaweiSection.Exists())
                {
                    config.HuaweiOBS = huaweiSection.Get<HuaweiObsConfiguration>();
                    _logger.LogInformation("已迁移HuaweiObs配置");
                }

                _logger.LogInformation($"已迁移CloudStorage配置，默认提供商: {config.CloudProvider}");
            }

            return config;
        }

        /// <summary>
        /// 验证本地存储配置
        /// </summary>
        private void ValidateLocalStorageConfiguration(UploadConfiguration local, CentralizedConfigurationValidationResult result)
        {
            if (local == null)
            {
                result.AddError("本地存储配置不能为空");
                return;
            }

            if (string.IsNullOrWhiteSpace(local.UploadPath))
            {
                result.AddError("本地存储根路径不能为空");
            }

            if (local.MaxFileSize <= 0)
            {
                result.AddError("文件大小限制必须大于0");
            }

            if (local.AllowedExtensions == null || local.AllowedExtensions.Count == 0)
            {
                result.AddWarning("未设置允许的文件扩展名，可能存在安全风险");
            }

            // 检查路径是否存在（如果是相对路径）
            try
            {
                var fullPath = Path.IsPathRooted(local.UploadPath) 
                    ? local.UploadPath 
                    : Path.Combine(Directory.GetCurrentDirectory(), local.UploadPath);

                if (!Directory.Exists(fullPath))
                {
                    result.AddWarning($"存储目录不存在: {fullPath}");
                }
            }
            catch (Exception ex)
            {
                result.AddError($"无法验证存储路径: {ex.Message}");
            }
        }

        /// <summary>
        /// 验证云存储配置
        /// </summary>
        private void ValidateCloudStorageConfiguration(CentralizedStorageConfiguration config, CentralizedConfigurationValidationResult result)
        {
            if (string.IsNullOrWhiteSpace(config.CloudProvider))
            {
                result.AddWarning("未指定云存储提供商");
                return;
            }

            switch (config.CloudProvider.ToLower())
            {
                case "aliyunoss":
                    if (config.AliyunOSS != null)
                    {
                        ValidateAliyunOSSConfiguration(config.AliyunOSS, result);
                    }
                    else
                    {
                        result.AddError("指定了AliyunOSS提供商但未配置相关参数");
                    }
                    break;

                case "tencentcos":
                    if (config.TencentCOS != null)
                    {
                        ValidateTencentCOSConfiguration(config.TencentCOS, result);
                    }
                    else
                    {
                        result.AddError("指定了TencentCOS提供商但未配置相关参数");
                    }
                    break;

                case "huaweiobs":
                    if (config.HuaweiOBS != null)
                    {
                        ValidateHuaweiOBSConfiguration(config.HuaweiOBS, result);
                    }
                    else
                    {
                        result.AddError("指定了HuaweiOBS提供商但未配置相关参数");
                    }
                    break;

                case "local":
                    // 本地存储已在上面验证
                    break;

                default:
                    result.AddError($"不支持的云存储提供商: {config.CloudProvider}");
                    break;
            }
        }

        /// <summary>
        /// 验证阿里云OSS配置
        /// </summary>
        private void ValidateAliyunOSSConfiguration(AliyunOssConfiguration config, CentralizedConfigurationValidationResult result)
        {
            if (string.IsNullOrWhiteSpace(config.AccessKeyId))
                result.AddError("阿里云OSS AccessKeyId不能为空");

            if (string.IsNullOrWhiteSpace(config.AccessKeySecret))
                result.AddError("阿里云OSS AccessKeySecret不能为空");

            if (string.IsNullOrWhiteSpace(config.Endpoint))
                result.AddError("阿里云OSS Endpoint不能为空");

            if (string.IsNullOrWhiteSpace(config.BucketName))
                result.AddError("阿里云OSS BucketName不能为空");

            if (!config.Enabled)
                result.AddWarning("阿里云OSS配置存在但未启用");
        }

        /// <summary>
        /// 验证腾讯云COS配置
        /// </summary>
        private void ValidateTencentCOSConfiguration(TencentCosConfiguration config, CentralizedConfigurationValidationResult result)
        {
            if (string.IsNullOrWhiteSpace(config.SecretId))
                result.AddError("腾讯云COS SecretId不能为空");

            if (string.IsNullOrWhiteSpace(config.SecretKey))
                result.AddError("腾讯云COS SecretKey不能为空");

            if (string.IsNullOrWhiteSpace(config.BucketName))
                result.AddError("腾讯云COS BucketName不能为空");

            if (string.IsNullOrWhiteSpace(config.Region))
                result.AddError("腾讯云COS Region不能为空");
        }

        /// <summary>
        /// 验证华为云OBS配置
        /// </summary>
        private void ValidateHuaweiOBSConfiguration(HuaweiObsConfiguration config, CentralizedConfigurationValidationResult result)
        {
            if (string.IsNullOrWhiteSpace(config.AccessKeyId))
                result.AddError("华为云OBS AccessKeyId不能为空");

            if (string.IsNullOrWhiteSpace(config.SecretAccessKey))
                result.AddError("华为云OBS SecretAccessKey不能为空");

            if (string.IsNullOrWhiteSpace(config.BucketName))
                result.AddError("华为云OBS BucketName不能为空");

            if (string.IsNullOrWhiteSpace(config.Endpoint))
                result.AddError("华为云OBS Endpoint不能为空");
        }
    }

    /// <summary>
    /// 集中化存储配置模型
    /// </summary>
    public class CentralizedStorageConfiguration
    {
        /// <summary>
        /// 云存储提供商 (Local, AliyunOSS, TencentCOS, HuaweiOBS)
        /// </summary>
        public string CloudProvider { get; set; } = "Local";

        /// <summary>
        /// 本地存储配置
        /// </summary>
        public UploadConfiguration Local { get; set; } = new UploadConfiguration();

        /// <summary>
        /// 阿里云OSS配置
        /// </summary>
        public AliyunOssConfiguration? AliyunOSS { get; set; }

        /// <summary>
        /// 腾讯云COS配置
        /// </summary>
        public TencentCosConfiguration? TencentCOS { get; set; }

        /// <summary>
        /// 华为云OBS配置
        /// </summary>
        public HuaweiObsConfiguration? HuaweiOBS { get; set; }

        /// <summary>
        /// 缓存配置
        /// </summary>
        public CacheSettings Cache { get; set; } = new CacheSettings();

        /// <summary>
        /// 安全配置
        /// </summary>
        public SecuritySettings Security { get; set; } = new SecuritySettings();
    }

    /// <summary>
    /// 缓存设置
    /// </summary>
    public class CacheSettings
    {
        public bool EnableMetadataCache { get; set; } = true;
        public int MetadataCacheExpiryMinutes { get; set; } = 30;
        public bool EnableContentCache { get; set; } = false;
        public int ContentCacheExpiryMinutes { get; set; } = 60;
    }

    /// <summary>
    /// 安全设置
    /// </summary>
    public class SecuritySettings
    {
        public bool EnableVirusScan { get; set; } = false;
        public bool EnableFileDeduplication { get; set; } = true;
        public string[] BlockedExtensions { get; set; } = { ".exe", ".bat", ".cmd", ".scr", ".vbs" };
    }

    /// <summary>
    /// 集中化配置验证结果
    /// </summary>
    public class CentralizedConfigurationValidationResult
    {
        public List<string> Errors { get; } = new List<string>();
        public List<string> Warnings { get; } = new List<string>();

        public void AddError(string error) => Errors.Add(error);
        public void AddWarning(string warning) => Warnings.Add(warning);
        
        public bool IsValid => Errors.Count == 0;
        public bool HasWarnings => Warnings.Count > 0;
    }
}
